package client;

import interfaces.TaskI;
import interfaces.WorkerI;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Properties;

/**
 * ClientHandler manage the communication with the Client and launch the worker
 *
 * @param <IN>
 * @param <OUT>
 */
public class ClientHandler<IN, OUT> {
	String ip = "127.0.0.1"; // localhost
	int port = 3141;
	private ObjectOutputStream oos = null;
	private ObjectInputStream ois = null;
	IN dataIN = null;
	TaskI<IN, OUT> task = null;
	String te = "test";
	OUT dataOut = null;

	public ClientHandler() throws IOException, InterruptedException {
		// verbindet sich mit Server
		Socket socket = new Socket(ip, port);
		getConfig();
		String message = "CONNECT TO CLIENT";
		System.out.println("Client running!");
		// String empfangeneNachricht
		// Anforderung senden
		sendMessage(socket, message);
		oos = new ObjectOutputStream(socket.getOutputStream());
		ois = new ObjectInputStream(socket.getInputStream());
		boolean full=true;
		getTaskFromServer(socket);
		Worker w=null;
		while (full) {
			getData(socket);
			
			if (dataIN!=null) {
				w = new Worker(dataIN, task);
				//TODO insert cached threadpool
				
				try {
					w.excute();
					dataOut=(OUT) w.getDataOut();
				} catch (Exception e) {
					System.out.println("dataOut=(OUT) w.call();");
					e.printStackTrace();
				}
				oos.writeObject(dataOut);
//				if (this.isAlive()) {
//					this.join();	
//				}
//				this.start();
				
				
			}else {
				full=false;
				System.out.println("datainput are empty");
			}
			
		}
		
		

		oos.close();
		ois.close();
		socket.close();
		System.out.println("Client Close!");

	}

	/**
	 * Fetch the Configfile and set the Server IP
	 */
	private void getConfig() {
		Properties configFile = new Properties();

		try {
			configFile .load(new FileInputStream("config.properties"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		ip = configFile.getProperty("serverip"); 
		port = Integer.parseInt(configFile.getProperty("socket")); 
		System.out.println("Server IP:"+ip);
		System.out.println("Server socket:"+port);
	
	}

	/**
	 * Send a message to the server 
	 * Implemented to test the connection between Server and client 
	 * 
	 * 
	 * @param socket
	 * @param message
	 * @throws IOException
	 */
	void sendMessage(Socket socket, String message) throws IOException {

		PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(
				socket.getOutputStream()));
		printWriter.print(message);
		printWriter.flush();
		//printWriter.close();//TODO test
	}

	/**
	 * 
	 * Fetch the Task from the Server
	 * @param socket
	 * @throws IOException
	 * 
	 */
	void getTaskFromServer(Socket socket) throws IOException {
		try {
			task = (TaskI) ois.readObject();
		} catch (Exception e) {
			System.out.println("getTaskFromServer(Socket socket) ERROR");
			e.printStackTrace();
		}

	}

	/**
	 * Fetch Data from Server
	 * 
	 * @param socket
	 */
	void getData(Socket socket) {
		System.out.println("client:try to fetch data ");
		
		try {
			dataIN = (IN) ois.readObject();
			if (("empty".equals(dataIN))) {
				System.out.println("No input dates");
				dataIN =null;
			}
		} catch (Exception e) {
			System.out
					.println("Client:IOException, dataIN = (IN) ois.readObject();");
			e.printStackTrace();
			dataIN =null;
		}
		//System.out.println("Client: got input dates");
	}


}
